package com.example.xquicdemo

import android.annotation.SuppressLint
import android.content.Intent
import android.net.sip.SipErrorCode.TIME_OUT
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import com.example.xquicdemo.RxUtils.TrustAllHostnameVerifier
import com.lizhi.component.net.xquic.XquicClient
import com.lizhi.component.net.xquic.listener.XCall
import com.lizhi.component.net.xquic.listener.XCallBack
import com.lizhi.component.net.xquic.listener.XDns
import com.lizhi.component.net.xquic.mode.XMediaType
import com.lizhi.component.net.xquic.mode.XRequest
import com.lizhi.component.net.xquic.mode.XRequestBody
import com.lizhi.component.net.xquic.mode.XResponse
import com.lizhi.component.net.xquic.native.AlpnType
import com.lizhi.component.net.xquic.native.ProtoVersion
import com.lizhi.component.net.xquic.utils.XLogUtils
import kotlinx.coroutines.*
import lecho.lib.hellocharts.model.PointValue
import okhttp3.*
import java.io.IOException
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
import javax.net.ssl.*


class TestMainActivity : BleActivity() {
     var clinet: OkHttpClient?=null
    private var launch: Job? = null
    private lateinit var xquicClient: XquicClient

    private var successCount = 0
    private var failCount = 0
    private var startTime = System.currentTimeMillis()
    private val atomicInteger = AtomicInteger()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test_main)
        loadCharShow()
        xquicClient = XquicClient.Builder()
            .connectTimeOut(SetCache.getConnTimeout(applicationContext))
            .ccType(SetCache.getCCType(applicationContext))
            .setReadTimeOut(SetCache.getConnTimeout(applicationContext))
            .writeTimeout(15)
            .dns(XDns.SYSTEM)
            .reuse(SetCache.getReuse(applicationContext) == 1)//默认值false
            .setProtoVersion(ProtoVersion.XQC_IDRAFT_VER_29)
            //.setAlpnType(AlpnType.ALPN_HQ)
            .build()
        findViewById<Button>(R.id.btn_config).setOnClickListener {
            val intent = Intent(this, SetActivity::class.java)
            startActivity(intent)
        }
        findViewById<Button>(R.id.btn_quic_1).setOnClickListener {
            xquicClient.ccType=0
            listQuic_1.clear()
            val testCount = SetCache.getTestCount(applicationContext)
            val methodGet = SetCache.getMethod(applicationContext) == "GET"
            val timeSpace = SetCache.getTestSpace(applicationContext)
            var textView=findViewById<TextView>(R.id.tv_text_quic_1)
            textView.setText("")
            launch = CoroutineScope(Dispatchers.Default).launch {
                startTime = System.currentTimeMillis()
                successCount = 0
                failCount = 0
                atomicInteger.set(0)
                for (i in (1..testCount)) {
                    if (methodGet) {
                        get(textView,i)
                    }
                    XLogUtils.error("=====================index($i) ===============")
//                    if (timeSpace > 0) {
//                        delay(timeSpace * 1000L)
//                    }
                }
            }
        }
        findViewById<Button>(R.id.btn_quic_2).setOnClickListener {
            xquicClient.ccType=1
            listQuic_2.clear()
            val testCount = SetCache.getTestCount(applicationContext)
            val methodGet = SetCache.getMethod(applicationContext) == "GET"
            val timeSpace = SetCache.getTestSpace(applicationContext)
            var textView=findViewById<TextView>(R.id.tv_text_quic_2)
            textView.setText("")
            launch = CoroutineScope(Dispatchers.Default).launch {
                startTime = System.currentTimeMillis()
                successCount = 0
                failCount = 0
                atomicInteger.set(0)
                for (i in (1..testCount)) {
                    if (methodGet) {
                        get(textView,i)
                    }
                    XLogUtils.error("=====================index($i) ===============")
//                    if (timeSpace > 0) {
//                        delay(timeSpace * 1000L)
//                    }
                }
            }

        }
        findViewById<Button>(R.id.btn_tcp).setOnClickListener {
            lisTtcp.clear()
            var textView=findViewById<TextView>(R.id.tv_text_tcp)
            textView.setText("")
            launch = CoroutineScope(Dispatchers.Default).launch {
                val  testCount= SetCache.getTestCount(applicationContext)
                for ( i in 1..testCount){
                    testTcp(i)
                }
            }
        }
    }


    /**
     * quic
     */
    private fun get(textView: TextView,index: Int) {

        val url = SetCache.getSelectUrl(applicationContext)
        if (url.isNullOrEmpty()) {
            Toast.makeText(applicationContext, "请先设置url", Toast.LENGTH_SHORT).show()
            return
        }
        val xRequestBody = XRequestBody.create(XMediaType(XMediaType.MEDIA_TYPE_TEXT), "")
        val xRequest = XRequest.Builder()
            .url("$url")
            .get(xRequestBody) //Default
            .addHeader("tenantId", "soacp")
            .addHeader("clientId", "portalApp")
            //.addHeader("testA", "testA")
            .addHeader("Keep-Alive", "timeout=300, max=1000")
            .tag("index:$index")
            .build()
        request(textView,index, xRequest)
    }
    private fun request(textView: TextView,index: Int, xRequest: XRequest) {
        if (index == 1) {
            val requestInfo = StringBuilder()
           // requestInfo.append("拥塞算法：" + SetCache.getCCType(applicationContext) + "\n")
           // requestInfo.append("链接超时：" + SetCache.getConnTimeout(applicationContext) + " 秒\n")
           // requestInfo.append("请求方式：" + SetCache.getMethod(applicationContext) + "\n")
            //requestInfo.append("轮询次数：" + SetCache.getTestCount(applicationContext) + " 次\n")
            //requestInfo.append("请求url：" + xRequest.url.url + "\n")
           // requestInfo.append("是否复用：" + xquicClient.reuse + "\n")
           // appendText(textView,requestInfo.toString())
        }
        startTime = System.currentTimeMillis()
        xquicClient.newCall(xRequest).enqueue(object : XCallBack {
            override fun onFailure(call: XCall, exception: Exception) {
                appendText(textView,"耗时${System.currentTimeMillis() - startTime}")
                //这是失败的
                exception.printStackTrace()
                XLogUtils.error(exception.message)
                synchronized(this@TestMainActivity) {
                    failCount++
                }
                atomicInteger.incrementAndGet()
                if (atomicInteger.get() >= SetCache.getTestCount(applicationContext)) {

                }
            }
            override fun onResponse(call: XCall, xResponse: XResponse) {
                //这是成功的
                writeBle {
                    appendText(textView,"耗时${System.currentTimeMillis() - startTime} ms")
                    if ( xquicClient.ccType==0){
                        listQuic_1.add(PointValue(index.toFloat(),(System.currentTimeMillis()-startTime).toFloat()))
                    }else{
                        listQuic_2.add(PointValue(index.toFloat(),(System.currentTimeMillis()-startTime).toFloat()))
                    }
                    if (SetCache.getTestCount(applicationContext)==index){
                        loadCharShow()
                    }
                    parseResponse(startTime, index, xResponse)
                    synchronized(this@TestMainActivity) {
                        successCount++
                    }
                    atomicInteger.incrementAndGet()
                    if (atomicInteger.get() >= SetCache.getTestCount(applicationContext)) {
                    }
                }

            }
        })
    }
    private fun parseResponse(startTime: Long, index: Int, xResponse: XResponse) {
        var content: String = xResponse.xResponseBody.body()
        if (content.length > 512 * 1024) {
            content = "数据太大，无法打印和显示，数据长度为:" + content.length
        }
        val now = System.currentTimeMillis()
        XLogUtils.error(
            "index=$index, java 总花费时长： ${(now - startTime)} ms,队列等待时长：${xResponse.delayTime} ms,请求响应时长：${now - startTime - xResponse.delayTime} ms,size=${content.length},tag=${xResponse.xResponseBody.tag},content=${content}"
        )
        //appendText("$content ,index=$index, time=${now - startTime - xResponse.delayTime}ms ,status=" + xResponse.getStatus())
    }

    /**
     * 普通tcp请求方式
     */
    private fun initOkHttpClient() {
        if (clinet == null) {
            synchronized(this) {
                if (clinet == null) {
                    val builder = OkHttpClient.Builder()
                    clinet = builder
                        .connectionPool(ConnectionPool(0,1,TimeUnit.SECONDS))
                        .sslSocketFactory(RxUtils.createSSLSocketFactory(),trustManager = RxUtils.TrustAllManager())
                        .hostnameVerifier(TrustAllHostnameVerifier())
                        .retryOnConnectionFailure(true).build()
                }
            }
        }
    }
    private fun testTcp(pos:Int){
        var okstart=System.currentTimeMillis()
        initOkHttpClient()
        val url = SetCache.getSelectUrl(applicationContext)?.replace("4433","8000/static")//?.replace("https","http")
        if (url.isNullOrEmpty()) {
            Toast.makeText(applicationContext, "请先设置url", Toast.LENGTH_SHORT).show()
            return
        }
        var request =  Request.Builder()
            .url(url)
            .header("Connection", "close")
            .build()
        clinet?.newCall(request)?.enqueue(object:Callback{
            override fun onFailure(call: Call, e: IOException) {
            }
            override fun onResponse(call: Call, response: Response) {
                writeBle {
                    var textView=findViewById<TextView>(R.id.tv_text_tcp)
                    val requestInfo = StringBuilder()
                    // requestInfo.append("请求url：" + url + "\n")
                    requestInfo.append("耗时${(System.currentTimeMillis()-okstart)} ms")
                    appendText(textView,requestInfo.toString())
                    runOnUiThread {
                        lisTtcp.add(PointValue(pos.toFloat(),(System.currentTimeMillis()-okstart).toFloat()))
                        if (SetCache.getTestCount(applicationContext)==pos){
                            loadCharShow()
                        }
                    }
                }
            }

        })

    }
    @SuppressLint("SimpleDateFormat")
    private fun getData(): String {
    return ""
    // return SimpleDateFormat("dd hh:mm:ss").format(Date())
    }
    private fun appendText(textView:TextView,context: String?) {
        textView.let {
            runOnUiThread {
                it.append(getData() + " : " + context + "\n")
                val scrollAmount = it.layout?.getLineTop(it.lineCount)!! - it.height
                if (scrollAmount > 0) {
                    it.scrollTo(0, scrollAmount)
                } else {
                    it.scrollTo(0, 0)
                }
            }
        }
    }
    override fun onDestroy() {
        super.onDestroy()
        launch?.cancel()
        xquicClient.cancel("tag")
    }


}